home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
sound
/
rukc10.zip
/
BORLAND.ZIP
/
MIDMEMBC.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-03-06
|
12KB
|
236 lines
PAGE 81,132
;mid$malloc
;mid$free
;-----------------------------------------------------------------------|
; ScanSoft (C)1993 Cornel H Huth ALL RIGHTS RESERVED |
;-----------------------------------------------------------------------|
; date: 06-Mar-93 |
; function: Memory routines for C compilers |
; that do not allow DOS allocations to be mixed with |
; _malloc allocations (including _calloc, etc.) |
; notes: This malady afflicts Borland C compilers |
; All registers saved since there's no telling what |
; registers the runtime code uses |
; |
; |
;The code below will work in either LARGE or HUGE memory modules. |
;It will not, as written, work in the medium model. With minor changes, |
;the medium model could be supported. Not needed, however, in the |
;medium model. |
; |
;This code was written with MASM 5.10A in mind though TASM should |
;handle it, too. |
; |
;To assemble: |
; |
; C>masm midmembc /mx; (/mx=preserve case on globals) |
; |
;Then do the following: |
; |
; Replace MIDIMEM.OBJ in RUCKMIDI.LIB: |
; |
; C>lib RUCKMIDI -midimem +midmembc; |
; |
;Before doing anything, read the BORLAND.FIX text file. It documents |
;what and how to make a Borland-workable RUCKMIDI.LIB. |
; |
;Note: This replacement module does not enable DOS-controlled UMBs as |
; the normal mid$malloc does. A safety call since I don't know how |
; Borland's memory manager would deal with it. |
; |
;Important: Unlike allocation through DOS (INT48), _malloc and _free |
; require DS->DGROUP |
;-----------------------------------------------------------------------|
WPTR EQU <WORD PTR>
.MODEL LARGE,PASCAL
.CODE
EXTRN _malloc:FAR
EXTRN _free:FAR
;MAXTRACKER is the number of allocations that can be open at
;any one time. Consider each open file to require one Track.
;A good MAXTRACKER value would be the total number of files you
;require to be open at one time plus 5. Each MAXTRACKER
;requires 6 bytes of code space. Unless you're starving for
;RAM, MAXTRACKER is fine at 254 (uses about 1.5K of code space.)
MAXTRACKER EQU 254
;TrackerFP stores far pointers as returned by _malloc
;so that _free can be used (_free requires exact FP match)
EVEN
TrackerFP dd MAXTRACKER DUP (0) ;32-bit segmented pointer of _malloc
dd 0 ;and required by _free
;TrackerSeg stores the 16-bit segment pointer converted from
;the far pointer returned by _malloc. See mid$malloc for how
;this is done. This is used as a lookup value in mid$free.
TrackerSeg dw MAXTRACKER DUP (0) ;thunk it to a 16-bit segment pointer
dw -1
;-----------------------------------------------------------------------|
; date: 31-Jan-93 |
; function: allocate memory |
; caller: FAR, ASSEMBLY |
; stack: n/a |
; in: bx=paragraphs to allocate |
; out: NC=ax=seg |
; CY=ax=8=not enough memory |
; uses: ax (return) |
; notes: call with bx=FFFF and bx returns w/ largest block free |
; (according to DOS) |
; |
;06-Mar-93-chh |
;-Need to preserve bx if making allocation since bx used as size to |
; on return. |
;-For Huge Model mode need to first push element size, the long count...|
; ...Large model just ignores the first two pushes. MS C7 anyway. |
;-Added DS reload |
; |
;-----------------------------------------------------------------------|
mid$malloc PROC USES cx dx si di es ds
cmp bx,-1 ;just asking for available memory?
jne mid$malloc01 ;no
mov ah,48h ;yes, regular DOS check should do
int 21h ;though RUCKMIDI never makes a memory
jmp SHORT mid$mallocXit ;inquiry...currently
mid$malloc01: mov cx,MAXTRACKER ;scan for next free descriptor
sub ax,ax ;0 indicates available
push cs
mov di,OFFSET TrackerSeg
pop es ;es:di->TrackSeg start
repne scasw
jne mid$mallocEx ;none available
mov ax,di
sub ax,OFFSET TrackerSeg+2 ;ax=available slot (word)
push bx ;RUCKUS needs this later
push ax ;save slot
sub ax,ax
inc ax ;(1) in case of huge model
push ax ;put size on stack (char)
dec ax ;(0) and high-word of elements
push ax ;on stack (always 0 for RUCKUS)
mov ax,bx ;paras requested
inc ax ;bump para request so we can norm it
shl ax,1 ;(thunk it would be more like it)
shl ax,1
shl ax,1
shl ax,1 ;paras to bytes
push ax ;low-word of request
mov ax,SEG DGROUP
mov ds,ax ;_malloc runtime needs it
call _malloc ;appease the Borland Gods
add sp,6 ;here dx:ax is far pointer to block
pop di ;get back slot
mov bx,dx ;check for null pointer return
or bx,ax ;allocation okay?
pop bx ;get size in paras back now
jz mid$mallocEx ;no
mov si,di ;word slot index for TrackerSeg
shl di,1 ;dword slot index for TrackerFP